package org.chen.scene.service.ollama;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.chen.common.scene.ollama.OllamaRequest;
import org.chen.common.scene.ollama.OllamaResponse;
import org.chen.common.scene.ollama.TourRecommendationResponse;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import java.time.Duration;

@Service
@Slf4j
public class TourRecommendationService {

    private final RestTemplate restTemplate;

    @Value("${ollama.scene.base-url:http://8.219.169.114:11434}")
    private String OLLAMA_BASE_URL;

    @Value("${ollama.scene.model2:bge-m3}")
    private String embeddingModel;

    @Value("${ollama.is_open}")
    private boolean isOpen;

    private static final String SYSTEM_PROMPT = """
            你是一名专业的旅游顾问。请根据景点的规模、特色、常见游玩项目和游客体验，推荐合理的游玩时长。
            要求：
            - 时长需覆盖大部分游客从入园到基本游览完成的时间
            - 不要仅给出最短时间，要体现完整体验所需
            - 只输出 JSON 格式，不要多余解释
            - 单位为小时
            输出格式示例：
            { "Recommend_Hours": 3 }
            景点：%s
            """;

    public TourRecommendationService(RestTemplate restTemplate) {
        this.restTemplate = restTemplate;
    }

    public TourRecommendationResponse getRecommendation(String attractionName) {
        try {
            if (!isOpen){
                return new TourRecommendationResponse("");
            }

            // 构建提示词
            String prompt = String.format(SYSTEM_PROMPT, attractionName);

            // 创建请求对象
            OllamaRequest request = new OllamaRequest();
            request.setModel(embeddingModel);
            request.setPrompt(prompt);
            request.setStream(false);

            OllamaRequest.Options options = new OllamaRequest.Options();
            options.setTemperature(0.3); // 降低温度以获得更一致的结果
            options.setNum_predict(128);  // 限制输出长度
            request.setOptions(options);

            // 设置请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.APPLICATION_JSON);

            HttpEntity<OllamaRequest> httpEntity = new HttpEntity<>(request, headers);

            log.info("调用Ollama API，景点: {}", attractionName);

            // 调用Ollama API
            ResponseEntity<OllamaResponse> responseEntity = restTemplate.postForEntity(
                    OLLAMA_BASE_URL + "/api/generate",
                    httpEntity,
                    OllamaResponse.class
            );

            OllamaResponse ollamaResponse = responseEntity.getBody();

            if (ollamaResponse != null && ollamaResponse.getResponse() != null) {
                log.info("收到Ollama响应: {}", ollamaResponse.getResponse());
                // 解析JSON响应
                return parseJsonResponse(ollamaResponse.getResponse());
            } else {
                throw new RuntimeException("未收到有效响应");
            }

        } catch (RestClientException e) {
            log.error("RestTemplate调用失败: {}", e.getMessage(), e);
            throw new RuntimeException("网络请求失败: " + e.getMessage());
        } catch (Exception e) {
            log.error("调用Ollama API失败: {}", e.getMessage(), e);
            throw new RuntimeException("获取推荐时长失败: " + e.getMessage());
        }
    }

    private TourRecommendationResponse parseJsonResponse(String jsonResponse) {
        try {
            ObjectMapper objectMapper = new ObjectMapper();

            // 清理响应文本，提取JSON部分
            String cleanJson = extractJsonFromResponse(jsonResponse);

            JsonNode jsonNode = objectMapper.readTree(cleanJson);
            String recommendMinutes = jsonNode.get("Recommend_Hours").asText("");

            return new TourRecommendationResponse(recommendMinutes);

        } catch (Exception e) {
            log.error("解析JSON响应失败: {}", e.getMessage());
            // 如果解析失败，返回默认值
            throw new RuntimeException("解析推荐时长失败: " + e.getMessage());
        }
    }

    private String extractJsonFromResponse(String response) {
        // 查找JSON部分
        int startIndex = response.indexOf("{");
        int endIndex = response.lastIndexOf("}");

        if (startIndex != -1 && endIndex != -1 && endIndex > startIndex) {
            return response.substring(startIndex, endIndex + 1);
        }

        throw new RuntimeException("无法从响应中提取有效的JSON");
    }
}